/*
 * Copyright (c) 2020-2099 the original author or authors. All rights reserve.
 */
package org.tianyun.cloud.config.refresh.smart;

import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;

/**
 * 配置变动刷新监听器
 * 调用链：
 * ①：EnvironmentChangeEvent->SmartRefresher.addChangedKeys
 * ②：RefreshScope.refreshAll()->RefreshScopeRefreshedEvent->SmartScope.refresh(keys)->SmartScopeRefreshedEvent->RefreshScopeRefreshedEvent
 *
 * @auther ebert_chan
 */
public class EnvironmentChangeEventListenner implements SmartApplicationListener {

    private SmartRefresher smartRefresher;

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    public EnvironmentChangeEventListenner(SmartRefresher smartRefresher) {
        this.smartRefresher = smartRefresher;
    }

    /*
     * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
     */
    @Override
    public void onApplicationEvent(ApplicationEvent event) {

        if (event instanceof EnvironmentChangeEvent) {
            EnvironmentChangeEvent environmentChangeEvent = (EnvironmentChangeEvent) event;
            smartRefresher.addChangedKeys(environmentChangeEvent.getKeys());
            return;
        }

        if (event instanceof RefreshScopeRefreshedEvent) {
            RefreshScopeRefreshedEvent refreshScopeRefreshedEvent = (RefreshScopeRefreshedEvent) event;
            if (!RefreshScopeRefreshedEvent.DEFAULT_NAME.equals(refreshScopeRefreshedEvent.getName())) {
                return;
            }
            smartRefresher.refreshOfChangedKeys();
        }

    }

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return EnvironmentChangeEvent.class.isAssignableFrom(eventType)
                || RefreshScopeRefreshedEvent.class.isAssignableFrom(eventType);
    }

}
